import 'package:ble_measure_plugin/utils/ext.dart';
import 'package:flutter_blue_plus/flutter_blue_plus.dart';

import '../ble_measure_plugin.dart';

abstract class BaseDeviceModel {
  void connect(BluetoothDevice device);

  EventHandlerMap<BluetoothConnectionState>? deviceStateHandler;

  void addDeviceStateListener(
      EventHandlerMap<BluetoothConnectionState>? deviceStateHandler) {
    this.deviceStateHandler = deviceStateHandler;
  }

  void release() {
    this.deviceStateHandler = null;
  }

  EventHandlerMap<String>? onStartConnectListener;
  EventHandlerMap<String>? onStartOpenListener;
  EventHandlerMap<String>? onOpenSuccessListener;
  EventHandlerMap<String>? onOpenFailListener;

  void addDeviceConnectListener(
      {EventHandlerMap<String>? onStartConnectListener,
      EventHandlerMap<String>? onStartOpenListener,
      EventHandlerMap<String>? onOpenSuccessListener,
      EventHandlerMap<String>? onOpenFailListener}) {
    this.onStartConnectListener = onStartConnectListener;
    this.onStartOpenListener = onStartOpenListener;
    this.onOpenSuccessListener = onOpenSuccessListener;
    this.onOpenFailListener = onOpenFailListener;
  }
}

abstract class BaseDeviceMeasureModel extends BaseDeviceModel {
  String get serviceUuid => "";

  String get characteristicWriteable => "";

  String get characteristicReadable => "";

  var hasConnect = false;
  var hasMeasure = false;

  BluetoothDevice? measureDevice;
  BluetoothCharacteristic? _readCharacteristic;
  BluetoothCharacteristic? _writeCharacteristic;
  BluetoothConnectionState? _deviceState = BluetoothConnectionState.disconnected;

  var hasListener = false;

  var canReconnect = true;

  @override
  void connect(BluetoothDevice device) {
    if (hasConnect) {
      return;
    }
    canReconnect = true;
    measureDevice = device;
    var inConnectProcess = false;
    measureDevice?.state.listen((event) async {
      if (event != BluetoothConnectionState.connected &&
          event != BluetoothConnectionState.connecting) {
        if (!canReconnect) {
          return;
        }
        print("开始连接======>${event}");
        inConnectProcess = true;
        hasConnect = true;
        onStartConnect();
        await measureDevice?.connect();
        BleMeasurePlugin.instance.linkDevices.add(device);
        inConnectProcess = false;
      } else {
        hasConnect = false;
        BleMeasurePlugin.instance.linkDevices.remove(device);
        inConnectProcess = false;
        hasMeasure = false;
        // _readCharacteristic.value
      }
      if (measureDevice != null) {
        if (event == BluetoothConnectionState.connected) {
          var discoverServices = await device.discoverServices();
          var inProcess = false;
          for (var service in discoverServices) {
            if (inProcess) {
              return;
            }
            if (service.uuid.toString() == serviceUuid) {
              for (var element in service.characteristics) {

                var chaUuid = element.uuid.toString();
                if (chaUuid == characteristicWriteable) {
                  _writeCharacteristic = element;
                }
                if (chaUuid == characteristicReadable) {
                  print("1111====>${element.uuid.toString()}");
                  _readCharacteristic = element;
                  // if (_readCharacteristic?.isNotifying == false) {
                    onStartOpen();
                    try {
                      await _readCharacteristic?.setNotifyValue(true);
                      onOpenSuccess();
                      print("开启成功.....");
                    } catch (e) {
                      onOpenFail();
                      print("开启失败.....");
                    }
                  // }else{
                  //   print("已经开启.....");
                  // }
                  if (!hasListener) {
                    _readCharacteristic?.value.listen((event) {
                      hasListener = true;
                      var va16 = event.map((e) {
                        var data = e.toRadixString(16).toUpperCase();
                        if (data.length == 1) {
                          data = "0$data";
                        }
                        return data;
                      }).toList();
                      if (va16.isNotEmpty) {
                        onReceiveData(va16);
                      }
                    });
                  }
                  break;
                }else{
                  print("123123123132");
                }
              }
            }
          }
        } else if (event == BluetoothConnectionState.disconnected) {
          BleMeasurePlugin.instance.linkDevices.remove(device);
        }
        if (deviceStateHandler != null && _deviceState != event) {
          _deviceState = event;
          deviceStateHandler!(event);
        }
      }
    });
  }

  void onReceiveData(List<String> data);

  Future<void> disconnect() async {
    BleMeasurePlugin.instance.linkDevices.remove(measureDevice);
    await measureDevice?.disconnect();
    release();
  }

  BaseDeviceMeasureModel() {
    init();
  }

  void init() {}

  void onOpenSuccess() {
    if(onOpenSuccessListener!=null){
      onOpenSuccessListener!("");
    }
  }

  @override
  Future<void> release() async {
    hasConnect = false;
    hasListener = false;
    canReconnect = false;
    _deviceState = BluetoothConnectionState.disconnected;
    await _readCharacteristic?.setNotifyValue(false);
    measureDevice = null;
    _readCharacteristic = null;
    _writeCharacteristic = null;
    super.release();
  }

  void onOpenFail() {
    if(onOpenFailListener!=null){
      onOpenFailListener!("");
    }
  }

  void onStartOpen() {
    if(onStartOpenListener!=null){
      onStartOpenListener!("");
    }
  }

  void onStartConnect() {
    if(onStartConnectListener!=null){
      onStartConnectListener!("");
    }
  }
}
